线程基础

1. 什么是线程?

在计算机科学中,线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一个进程可以包含多个线程,这些线程共享进程的资源,如内存空间。

1.1 线程的优势

  • 并发性:多个线程可以在同一时间内执行不同的任务,从而提高程序的响应速度和效率。
  • 资源共享:线程之间可以共享进程的资源,如内存,这使得线程间的通信更加高效。
  • 轻量级:相比于进程,线程的创建和销毁开销更小。

2. Ruby 中的线程

Ruby 提供了对线程的支持,使得开发者可以轻松地创建和管理多线程程序。Ruby 的线程是用户级线程,这意味着它们由 Ruby 解释器管理,而不是操作系统。

2.1 创建线程

在 Ruby 中,你可以使用 Thread.new 方法来创建一个新的线程。线程的代码块会在新线程中执行。

thread = Thread.new do
  puts "Hello from a new thread!"
end

thread.join # 等待线程执行完毕

2.2 线程的生命周期

  • 创建:使用 Thread.new 创建线程。
  • 执行:线程的代码块开始执行。
  • 结束:线程的代码块执行完毕,线程结束。

2.3 线程的同步

在多线程编程中,线程同步是一个重要的问题。线程同步确保多个线程不会同时访问共享资源,从而避免数据竞争和不一致。

2.3.1 互斥锁(Mutex)

Ruby 提供了 Mutex 类来实现互斥锁。互斥锁确保同一时间只有一个线程可以访问共享资源。

mutex = Mutex.new

thread1 = Thread.new do
  mutex.lock
  puts "Thread 1 is accessing the shared resource."
  sleep(2)
  puts "Thread 1 is done."
  mutex.unlock
end

thread2 = Thread.new do
  mutex.lock
  puts "Thread 2 is accessing the shared resource."
  sleep(2)
  puts "Thread 2 is done."
  mutex.unlock
end

thread1.join
thread2.join

2.4 线程的状态

线程有多种状态,包括:

  • 运行:线程正在执行。
  • 阻塞:线程被阻塞,等待某个事件发生。
  • 终止:线程已经执行完毕。

你可以使用 Thread#status 方法来检查线程的状态。

thread = Thread.new { sleep(5) }
puts thread.status # 输出 "sleep" 或 "run"

3. 实践练习

3.1 练习:创建多个线程

编写一个 Ruby 程序,创建多个线程,每个线程打印一条消息,并确保主线程等待所有子线程完成后再退出。

threads = []

5.times do |i|
  threads << Thread.new do
    puts "Thread #{i} is running."
    sleep(1)
    puts "Thread #{i} is done."
  end
end

threads.each(&:join)
puts "All threads are done."

3.2 练习:使用互斥锁

编写一个 Ruby 程序,使用互斥锁来确保多个线程不会同时访问共享资源。

mutex = Mutex.new
shared_resource = 0

threads = []

5.times do |i|
  threads << Thread.new do
    mutex.lock
    shared_resource += 1
    puts "Thread #{i} incremented shared_resource to #{shared_resource}."
    mutex.unlock
  end
end

threads.each(&:join)
puts "Final value of shared_resource: #{shared_resource}"

4. 总结

线程是多任务处理的重要工具,Ruby 提供了强大的线程支持,使得开发者可以轻松地创建和管理多线程程序。通过理解线程的基本概念、创建方法、同步机制和状态管理,你可以编写出高效、可靠的多线程应用程序。

希望这篇教程能帮助你更好地理解 Ruby 中的线程基础。继续探索和实践,你将能够掌握更多高级的线程编程技巧。